﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.Management;
using System.Diagnostics;

namespace uLib.Helper
{
    public class SecurityHelper
    {
        public bool IsAdministrator()
        {
            WindowsIdentity myWindowsIdentity = WindowsIdentity.GetCurrent();
            WindowsPrincipal myWindowsPrincipal = new WindowsPrincipal(myWindowsIdentity);
            return myWindowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
        }

        public List<String> getGroupsOfMember(string username)
        {
            List<string> groups = new List<string>();

            using (DirectorySearcher searcher = new DirectorySearcher(new DirectoryEntry(string.Empty)))
            {
                searcher.Filter = string.Concat(string.Format(@"(&(ObjectClass=user)(sAMAccountName={0}))", username));

                foreach (SearchResult result in searcher.FindAll())
                {
                    foreach (var group in result.Properties["MemberOf"])
                    {
                        string groupResult = group as string;

                        if (groupResult != null)
                        {
                            groups.Add(groupResult.Substring(3, groupResult.IndexOf(',') - 3));
                        }
                    }
                }
            }

            if (groups.Count < 1)
                groups.Add("- kein Eintrag gefunden -");

            return groups;
        }

        public List<string> getMemberOfGroup(string group)
        {
            List<string> members = new List<string>();

            using (DirectorySearcher searcher = new DirectorySearcher(new DirectoryEntry(string.Empty)))
            {
                searcher.Filter = string.Format(@"(&(objectClass=group)(cn={0}))", group);

                foreach (SearchResult result in searcher.FindAll())
                {
                    foreach (var member in result.Properties["member"])
                    {
                        using (DirectoryEntry memberResult = new DirectoryEntry(string.Format("LDAP://{0}", member)))
                        {
                            string username = null;

                            try
                            {
                                username = memberResult.Properties["sAMAccountName"].Value as string;
                            }
                            catch (Exception)
                            {
                                username = memberResult.Path.Substring(0, memberResult.Path.IndexOf(','))
                                                            .Replace("LDAP://CN=", string.Empty);
                            }

                            if (username != null)
                                members.Add(username);
                        }
                    }
                }
            }

            if (members.Count < 1)
                members.Add("- kein Eintrag gefunden -");

            return members;
        }

        public string getUserNamefromSID(System.Security.Principal.SecurityIdentifier SID)
        {
            System.Security.Principal.NTAccount NTUser = (System.Security.Principal.NTAccount)SID.Translate(typeof(System.Security.Principal.NTAccount));
            return NTUser.ToString();
        }

        public static Dictionary<string, string> getLocalGroupMemberShip(string ComputerName, string UserName)
        {
            Dictionary<string, string> LocalGroups = new Dictionary<string, string>();
            ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Group WHERE LocalAccount = TRUE");
            ManagementScope ms = new ManagementScope("\\\\" + ComputerName + "\\root\\cimv2");
            mos.Scope = ms;
            try
            {
                mos.Scope.Connect();
            }
            catch (Exception)
            {
                return null;
            }

            foreach (ManagementObject mo in mos.Get())
            {
                ManagementObjectSearcher userSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_GroupUser Where GroupComponent = \"Win32_Group.Domain=\'" + ComputerName + "\',Name=\'" + mo["Name"] + "\'\"");
                userSearcher.Scope = ms;
                try
                {
                    userSearcher.Scope.Connect();
                    foreach (ManagementObject userObject in userSearcher.Get())
                    {
                        string UName = userObject["PartComponent"].ToString();
                        UName = UName.Substring(UName.IndexOf("=") + 1);
                        string Domain = UName.Substring(0, UName.IndexOf((","))).Replace("\"", "");
                        UName = UName.Substring(UName.IndexOf("=") + 1).Replace("\"", "");
                        if (UName.IndexOf(UserName, 0, StringComparison.OrdinalIgnoreCase) == 0)
                            LocalGroups.Add(mo["Name"].ToString(), Domain + "\\" + UName);
                    }
                }
                catch (Exception)
                {
                }
            }
            return LocalGroups;
        }

        public static string getLocalUserRights(string ComputerName, string UserName)
        {
            Dictionary<string, string> LocalRights = new Dictionary<string, string>();
            ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Group WHERE LocalAccount = TRUE");
            ManagementScope ms = new ManagementScope("\\\\" + ComputerName + "\\root\\cimv2");
            mos.Scope = ms;
            try
            {
                mos.Scope.Connect();
            }
            catch (Exception)
            {
                return null;
            }
            SecurityIdentifier sidLocalAdmins = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
            SecurityIdentifier sidLocalPowerUser = new SecurityIdentifier(WellKnownSidType.BuiltinPowerUsersSid, null);
            SecurityIdentifier sidLocalUser = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);

            foreach (ManagementObject mo in mos.Get())
            {
                if (mo["SID"].ToString() == sidLocalAdmins.Value | mo["SID"].ToString() == sidLocalPowerUser.Value | mo["SID"].ToString() == sidLocalUser.Value)
                {
                    ManagementObjectSearcher userSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_GroupUser Where GroupComponent = \"Win32_Group.Domain=\'" + ComputerName + "\',Name=\'" + mo["Name"] + "\'\"");
                    userSearcher.Scope = ms;
                    try
                    {
                        userSearcher.Scope.Connect();
                        foreach (ManagementObject userObject in userSearcher.Get())
                        {
                            string UName = userObject["PartComponent"].ToString();
                            UName = UName.Substring(UName.IndexOf("=") + 1);
                            UName = UName.Substring(UName.IndexOf("=") + 1).Replace("\"", "");
                            if (UName.IndexOf(UserName, 0, StringComparison.OrdinalIgnoreCase) == 0)
                                LocalRights.Add(mo["SID"].ToString(), mo["Name"].ToString());
                        }
                    }
                    catch (Exception)
                    {
                    }
                }
            }
            if (LocalRights.ContainsKey(sidLocalAdmins.Value)) return LocalRights[sidLocalAdmins.Value];
            if (LocalRights.ContainsKey(sidLocalPowerUser.Value)) return LocalRights[sidLocalPowerUser.Value];
            if (LocalRights.ContainsKey(sidLocalUser.Value)) return LocalRights[sidLocalUser.Value];
            string UserAccount = sidLocalUser.Translate(typeof(NTAccount)).Value;
            return UserAccount.Substring(UserAccount.IndexOf("\\") + 1);
        }

        public static void lockDisplay()
        {
            Process.Start("rundll32.exe", "user32.dll,LockWorkStation");
        }
    }
}
